#include "oled_font.h"
#include "oled_display.h"
static unsigned char g_DisplayMemory[8][128];//显示内容现存
static VirtualHardware_enum_t oled_vhw = vSPI_2;
#define   FONT_CHINESE_INDEX_SIZE   sizeof(FontChineseIndex)

typedef enum
{
	ASCII,
	CHINESE,
	BATTERY,
	LOGO,
}Font_enum_t;



/**
  * @brief  将要显示的内容放在现存中相应的位置
  *         
  * @note     
  * @param  x：0~127   y：0~7
  * @param  pStr：指向需要显示的字符串
  * @param  disMode：显示模式：0正常显示，0XFF反显
  * @param  bold：1加粗   0正常
  */
static void displayDataInPutDisplayMemory(uint8_t x,uint8_t y, const uint8_t *pData,uint16_t  disMode,uint8_t bold,Font_enum_t  font)
{

	uint8_t DisData, LastLineData = 0;
	uint8_t i;
	uint8_t tmp_buff[24];
	
      if(font == ASCII)
      {
	  for (i=0; i<8; i++)
	  {
	    DisData = pData[i] | LastLineData;
	    if (bold)
	    {
	      LastLineData = pData[i];
	    }
	    tmp_buff[i] = (DisData ^ (disMode&0xff));
	  }
	  memcpy(&g_DisplayMemory[y][x],tmp_buff,8);
	  LastLineData =0;
	for (i=0; i<8; i++)
	{
		DisData = pData[i+8] | LastLineData;
		if (bold)
		{
			LastLineData = pData[i+8];
		}
		tmp_buff[i] = (DisData ^ (disMode&0xff));
	}
	memcpy(&g_DisplayMemory[y+1][x],tmp_buff,8);
	}
	else if(CHINESE == font)
	{
		for (i=0; i<16; i++)
	       {
		    DisData = pData[i] | LastLineData;
		    if (bold)
		    {
		      LastLineData = pData[i];
		    }
		    tmp_buff[i] = (DisData ^ (disMode&0xff));
	       }
	       memcpy(&g_DisplayMemory[y][x],tmp_buff,16);
	       LastLineData =0;
		for (i=0; i<16; i++)
		{
			DisData = pData[i+16] | LastLineData;
			if (bold)
			{
				LastLineData = pData[i+16];
			}
			tmp_buff[i] = (DisData ^ (disMode&0xff));
		}
		memcpy(&g_DisplayMemory[y+1][x],tmp_buff,16);
	}
	else if(BATTERY == font)
	{
		memcpy(&g_DisplayMemory[y][x],pData,14);//显示电池图标
	}
	else if(LOGO == font)
	{
		for (i=0; i<24; i++)
	       {
		    DisData = pData[i] | LastLineData;
		    if (bold)
		    {
		      LastLineData = pData[i];
		    }
		    tmp_buff[i] = (DisData ^ (disMode&0xff));
	       }
	       memcpy(&g_DisplayMemory[y][x],tmp_buff,24);
	       LastLineData =0;
		for (i=0; i<24; i++)
		{
			DisData = pData[i+24] | LastLineData;
			if (bold)
			{
				LastLineData = pData[i+24];
			}
			tmp_buff[i] = (DisData ^ (disMode&0xff));
		}
		memcpy(&g_DisplayMemory[y+1][x],tmp_buff,24);
	}
	
}



/**
  * @brief  OLED 直接显示字符串
  *         
  * @note  
  * @param  x：0~127   y：0~7
  * @param  pStr：指向需要显示的字符串
  * @param  disMode：显示模式：0正常显示，0XFF反显
  * @param  bold：1加粗   0正常
  */
void Oled_DisString(uint8_t x, uint8_t y,const char*pStr, uint16_t disMode, uint8_t bold)
{
  uint32_t addr;
  uint32_t i =0;

  while (*pStr)
  {
	if(strncmp(pStr,"[O]",3) == 0)
	{
	     displayDataInPutDisplayMemory(x,y,&fontLogo24X16[0* 48],disMode,bold,LOGO);
	      x += 24;
	      pStr += 3;
	}
	else if(strncmp(pStr,"[1]",3) == 0)
	{
	      displayDataInPutDisplayMemory(x,y,&fontLogo24X16[1* 48],disMode,bold,LOGO);
	      x += 24;
	      pStr += 3;
	}
	else if(strncmp(pStr,"[2]",3) == 0)
	{
		 displayDataInPutDisplayMemory(x,y,&fontLogo24X16[2* 48],disMode,bold,LOGO);
	      x += 24;
	      pStr += 3;
	}
	else if(strncmp(pStr,"[U]",3) == 0)
	{
		 displayDataInPutDisplayMemory(x,y,&fontLogo24X16[3* 48],disMode,bold,LOGO);
	         x += 24;
	         pStr += 3;
	}
	else if(strncmp(pStr,"[A]",3) == 0)
	{
		 displayDataInPutDisplayMemory(x,y,&fontLogo24X16[4* 48],disMode,bold,LOGO);
	         x += 24;
	        pStr += 3;
	}
	else if (*pStr >= ' ' && *pStr <= '~')//英文字符
	{
		addr =  (*pStr -' ')*16;
		displayDataInPutDisplayMemory(x,y,fontAscii8X16+addr,disMode,bold,ASCII);
		x += 8;
		if (x >= 128)
		{
			x = 0;
			y += 2;
		}
		pStr++;
	}
	else                              //中文字符
	{
	      for (i=0; FontChineseIndex[i]; i+=2)
	      {
	        if ((pStr[0]&0xff) == FontChineseIndex[i] && (pStr[1]&0xff) == FontChineseIndex[i+1])
	        {
	          displayDataInPutDisplayMemory(x,y,&fontChinese16x16[i * 16],disMode,bold,CHINESE);
	          break;
	        }
		 if(FONT_CHINESE_INDEX_SIZE < i) break;
	      }
	      x += 16;
	      pStr += 2;
	  }
  }
   Device_Write(oled_vhw,g_DisplayMemory,sizeof(g_DisplayMemory), 0);
}


/**
  * @brief  字符串内容写入显示缓存，此时不会更新显示 
  * @note   必须调用Oled_RefreshDisplay()函数才会更新显示
  * @param  x：0~127   y：0~7
  * @param  pStr：指向需要显示的字符串
  * @param  disMode：显示模式：0正常显示，0XFF反显
  * @param  bold：1加粗   0正常
  */
 
void Oled_DisStringInPutDisplayMemory(uint8_t x, uint8_t y,const char*pStr, uint16_t disMode, uint8_t bold)
{
  uint32_t addr;
  uint32_t i =0;

  while (*pStr)
  {
	if(strncmp(pStr,"[O]",3) == 0)
	{
	     displayDataInPutDisplayMemory(x,y,&fontLogo24X16[0* 48],disMode,bold,LOGO);
	      x += 24;
	      pStr += 3;
	}
	else if(strncmp(pStr,"[1]",3) == 0)
	{
	      displayDataInPutDisplayMemory(x,y,&fontLogo24X16[1* 48],disMode,bold,LOGO);
	      x += 24;
	      pStr += 3;
	}
	else if(strncmp(pStr,"[2]",3) == 0)
	{
		 displayDataInPutDisplayMemory(x,y,&fontLogo24X16[2* 48],disMode,bold,LOGO);
	      x += 24;
	      pStr += 3;
	}
	else if(strncmp(pStr,"[U]",3) == 0)
	{
		 displayDataInPutDisplayMemory(x,y,&fontLogo24X16[3* 48],disMode,bold,LOGO);
	         x += 24;
	         pStr += 3;
	}
	else if(strncmp(pStr,"[A]",3) == 0)
	{
		 displayDataInPutDisplayMemory(x,y,&fontLogo24X16[4* 48],disMode,bold,LOGO);
	         x += 24;
	        pStr += 3;
	}
	else if (*pStr >= ' ' && *pStr <= '~')//英文字符
	{
		addr =  (*pStr -' ')*16;
		displayDataInPutDisplayMemory(x,y,fontAscii8X16+addr,disMode,bold,ASCII);
		x += 8;
		if (x >= 128)
		{
			x = 0;
			y += 2;
		}
		pStr++;
	}
	else                              //中文字符
	{
	      for (i=0; FontChineseIndex[i]; i+=2)
	      {
	        if ((pStr[0]&0xff) == FontChineseIndex[i] && (pStr[1]&0xff) == FontChineseIndex[i+1])
	        {
	          displayDataInPutDisplayMemory(x,y,&fontChinese16x16[i * 16],disMode,bold,CHINESE);
	          break;
	        }
		 if(FONT_CHINESE_INDEX_SIZE < i) break;
	      }
	      x += 16;
	      pStr += 2;
	  }
  }
}


/**
  * @brief  显示电量图标
  *
  * @note
  * @param  x：0~127   y：0~7
  * @param  电量：0~10
  */
void Oled_DisElectricity(uint8_t x, uint8_t y, uint8_t electricity)
{
	uint8_t i, temp[14];
	const uint8_t imageBattery[14] = { 0x3F,   //电池图标
	                                   0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
	                                   0x3F,0x1E,0x1E
	                                 };
	for (i=0; i<14; i++)
	{
		temp[i] = imageBattery[i];
		if (i >= 1 && electricity)
		{
			temp[i] = 0X3F;
			electricity--;
		}
	}
    displayDataInPutDisplayMemory(x,y,temp,0,0,BATTERY);
}



/**
  * @brief  清除显存数据 不做实际清屏动作
  *
  * @note
  * @param  NULL
  * @param   NULL
  */
void Oled_DisplayClear(void)
{
	memset(g_DisplayMemory,0,sizeof(g_DisplayMemory));
	// Oled_Clear();
}

/**
  * @brief  将显存的数据刷新到OLED上显示
  *
  * @note
  * @param  DeviceHandle_t  handle
  * @param  
  */
void Oled_RefreshDisplay(void)
{
	Oled_Refresh_Gram((uint8_t*)g_DisplayMemory);
}

void Oled_AllWhiteTest(void)
{
	memset(g_DisplayMemory,0xFF,sizeof(g_DisplayMemory));
}











